//
//  WBEngineSina.m
//  PUDemo
//
//  Created by JK.Peng on 13-2-22.
//  Copyright (c) 2013年 njut. All rights reserved.
//

#import "WBEngineSina.h"
#import "SFHFKeychainUtils.h"
#import "OFUtil.h"

#define kSinaWeiboSDKAPIDomain             @"https://open.weibo.cn/2/"
#define kSinaWeiboSDKOAuth2APIDomain       @"https://open.weibo.cn/2/oauth2/"
#define kSinaWeiboWebAuthURL               @"https://open.weibo.cn/2/oauth2/authorize"
#define kSinaWeiboWebAccessTokenURL        @"https://open.weibo.cn/2/oauth2/access_token"

#define kSinaWeiboAppAuthURL_iPhone        @"sinaweibosso://login"
#define kSinaWeiboAppAuthURL_iPad          @"sinaweibohdsso://login"


#define kSinaSSOCallbackScheme        [NSString stringWithFormat:@"sinaweibosso.%@://", self.appKey]

#define kWBSinaTokenKey               @"access_token"

#define kWBKeychainOauth2SinaUserId [NSString stringWithFormat:@"%@_WeiBoOauth2SinaUserId",[self urlSchemeString]]

@implementation WBEngineSina
@synthesize userId = _userId;

- (void)dealloc
{
    [_userId release], _userId = nil;
    [super dealloc];
}

- (id)initWithAppKey:(NSString *)theAppKey appSecret:(NSString *)theAppSecret
{
    self = [super initWithAppKey:theAppKey appSecret:theAppSecret type:kOFTypeSina];
    if (self) {
    }
    return self;
}

#pragma mark - OFAuthorizeOauth2DataSource
- (NSString *)authorizeOauth2AuthorizeURL:(OFAuthorizeOauth2 *)authorize
{
    NSMutableDictionary * params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                    _appKey, @"client_id",
                                    SINA_REDIRECT_URI, @"redirect_uri",
                                    @"code", @"response_type",
                                    @"mobile", @"display",
                                    nil];
    return [OFRequest serializeURL:kSinaWeiboWebAuthURL
                            params:params
                        httpMethod:@"GET"];
}

- (OFRequest *)authorizeOauth2WBRequestForAccessToken:(OFAuthorizeOauth2 *)authorize authorizeCode:(NSString *)code
{
    NSMutableDictionary * params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                    _appKey, @"client_id",
                                    SINA_REDIRECT_URI, @"redirect_uri",
                                    _appSecret, @"client_secret",
                                    @"authorization_code", @"grant_type",
                                    code,@"code",
                                    nil];
    
    return [self generateRequestWithUrl:kSinaWeiboWebAccessTokenURL
                             httpMethod:@"POST"
                                 params:params
                           postDataType:kOFRequestPostDataTypeNormal
                       httpHeaderFields:nil
                               delegate:authorize];
}

#pragma mark - WBAuthorizeOauth2Delegate
- (OFAuthorizeParseResult *)authorizeOauth2:(OFAuthorizeOauth2 *)authorize parseAuthorizeCode:(NSString *)string
{
    OFAuthorizeParseResult * result = [[[OFAuthorizeParseResult alloc] init] autorelease];
    NSArray * pairsAry = [string componentsSeparatedByString:@"&"];
    for (NSString * pairString in pairsAry) {
        NSArray * pair = [pairString componentsSeparatedByString:@"="];
        if ([pair count] == 2) {
            if ([[pair objectAtIndex:0] isEqualToString:@"code"]) {
                result.authorizeCode = [pair objectAtIndex:1];
            } else if ([[pair objectAtIndex:0] isEqualToString:@"error_code"]) {
                result.authorizeCode = [pair objectAtIndex:1];
                result.authorizeErrorCode = YES;
            }
        }
    }
    if (result.authorizeCode) {
        return result;
    } else {
        return nil;
    }
}

- (BOOL)authorizeOauth2:(OFAuthorizeOauth2 *)authorize parseAccessToken:(NSString *)string
{
    NSError* error = nil;
	id result = [self parseJSONString:string error:&error];
	
	if (!error && [result isKindOfClass:[NSDictionary class]]){
        NSDictionary * dict = result;
        self.accessToken = [dict objectForKey:@"access_token"];
        self.userId = [dict objectForKey:@"uid"];
        self.expireTime = [[dict objectForKey:@"expires_in"] doubleValue]+[[NSDate date] timeIntervalSince1970];
        if (self.accessToken && self.userId && self.expireTime > 0) {
            return YES;
        }
    }
    return NO;
}

/**
 * @description sso回调方法，官方客户端完成sso授权后，回调唤起应用，应用中应调用此方法完成sso登录
 * @param url: 官方客户端回调给应用时传回的参数，包含认证信息等
 * @return YES
 */
- (BOOL)handleOpenURL:(NSURL *)url
{
    NSString *urlString = [url absoluteString];
    if ([urlString hasPrefix:kSinaSSOCallbackScheme])
    {
        if (!_ssoLoggingIn)
        {
            // sso callback after user have manually opened the app
            // ignore the request
        }
        else
        {
            _ssoLoggingIn = NO;
            BOOL   succeed = NO;
            if ([OFRequest getParamValueFromUrl:urlString paramName:@"sso_error_user_cancelled"])
            {
                
            }
            else if ([OFRequest getParamValueFromUrl:urlString paramName:@"sso_error_invalid_params"])
            {
                
            }
            else if ([OFRequest getParamValueFromUrl:urlString paramName:@"error_code"])
            {
                
            }
            else
            {
                self.accessToken = [OFRequest getParamValueFromUrl:urlString paramName:@"access_token"];
                self.userId = [OFRequest getParamValueFromUrl:urlString paramName:@"uid"];
                
                NSString *expires_in = [OFRequest getParamValueFromUrl:urlString paramName:@"expires_in"];
                self.expireTime = [expires_in doubleValue]+[[NSDate date] timeIntervalSince1970];
                
                if (self.accessToken && self.userId && self.expireTime > 0) {
                    succeed = YES;
                }
            }
            
            if (succeed) {
                [self saveAuthorizeData];
                [self delegateEngineDidLogIn];
            }else{
                [self delegateEngineDidFailToLogInWithError:nil];
            }
        }
    }
    return YES;
}

#pragma mark - Overwrite superclass
- (void)logIn
{
    if ([self isLoggedIn])
    {
        [self delegateEngineAlreadyLoggedIn];
        return;
    }
    
    _ssoLoggingIn = NO;
    // open sina weibo app
    UIDevice *device = [UIDevice currentDevice];
    if ([device respondsToSelector:@selector(isMultitaskingSupported)] &&
        [device isMultitaskingSupported])
    {
        NSDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                self.appKey, @"client_id",
                                SINA_REDIRECT_URI, @"redirect_uri",
                                kSinaSSOCallbackScheme, @"callback_uri", nil];
        
        NSString *appAuthURL = [OFRequest serializeURL:kSinaWeiboAppAuthURL_iPhone
                                                params:params
                                            httpMethod:@"GET"];
        _ssoLoggingIn = [[UIApplication sharedApplication] openURL:[NSURL URLWithString:appAuthURL]];
    }
    
    if(!_ssoLoggingIn){
        if (self.authorize) {
            return;
        }
        
        // open authorize view
        [self startAuthorize];
    }
}
#pragma mark - Private
- (OFRequest *)generateRequestWithUrl:(NSString *)url
                           httpMethod:(NSString *)httpMethod
                               params:(NSMutableDictionary *)params
                         postDataType:(OFRequestPostDataType)postDataType
                     httpHeaderFields:(NSDictionary *)httpHeaderFields
                             delegate:(id<OFRequestDelegate>)delegate
{
    return [self generateRequestWithUrl:url
                             httpMethod:httpMethod
                                 params:params
                           postDataType:postDataType
                       httpHeaderFields:httpHeaderFields
                               tokenKey:kWBSinaTokenKey
                               delegate:delegate];
}

#pragma mark - Overwrite
- (BOOL)isLoggedIn
{
    return ([super isLoggedIn] && _userId);
}

- (void)saveAuthorizeData
{
    [[NSUserDefaults standardUserDefaults] setObject:_userId forKey:kWBKeychainOauth2SinaUserId];
    [super saveAuthorizeData];
}

- (void)readAuthorizeData
{
    self.userId = [[NSUserDefaults standardUserDefaults] objectForKey:kWBKeychainOauth2SinaUserId];
    [super readAuthorizeData];
}

- (void)deleteAuthorizeData
{
    self.userId = nil;
    [super deleteAuthorizeData];
}

#pragma mark - API
#pragma mark 转换短链接 使用AppKey
- (void)covertToShort_urlWithLongUrl:(NSString *)url
{
    if (!url || [url isEqualToString:@""]) {
        return;
    }
    
    NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:2];
    [params setObject:url forKey:@"url_long"];
    [params setObject:@"2679290066" forKey:@"source"];
//	[params setObject:self.appKey forKey:@"source"];
    
    [self loadApiKeyRequestWithUrl:@"https://api.weibo.com/2/short_url/shorten.json"
                        httpMethod:@"GET"
                            params:params
                      postDataType:kOFRequestPostDataTypeNone
                  httpHeaderFields:nil];
}

- (void)requestFriendsTimelineWithSinceId:(NSString *)sinceId
                                    maxId:(NSString *)maxId
                                   length:(NSInteger)length
{
    NSMutableDictionary * params = [NSMutableDictionary dictionaryWithCapacity:0];
    if (sinceId) {
        [params setObject:sinceId forKey:@"since_id"];
    }
    if (maxId) {
        [params setObject:maxId forKey:@"max_id"];
    }
    if (length > 0) {
        [params setObject:[NSString stringWithFormat:@"%d", length] forKey:@"count"];
    }
    
    [self loadRequestWithUrl:@"https://api.weibo.com/2/statuses/friends_timeline.json"
                  httpMethod:@"GET"
                      params:params
                postDataType:kOFRequestPostDataTypeNone
            httpHeaderFields:nil];
}

- (void)repostWeiboWithWeiboId:(NSString *)weiboId
                          text:(NSString *)text
                   commentType:(OFRepostCommentType)commentType
{
    if (!weiboId) {
        return;
    }
    
    NSMutableDictionary * params = [NSMutableDictionary dictionaryWithCapacity:0];
    [params setObject:weiboId forKey:@"id"];
    
    if (text) {
        [params setObject:text forKey:@"status"];
    }
    
    [params setObject:[NSString stringWithFormat:@"%d", (int)commentType] forKey:@"is_comment"];
    
    [self loadRequestWithUrl:@"https://api.weibo.com/2/statuses/repost.json"
                  httpMethod:@"POST"
                      params:params
                postDataType:kOFRequestPostDataTypeNormal
            httpHeaderFields:nil];
    
}

- (void)sendWeiBoWithText:(NSString *)text image:(UIImage *)image
{
    if (!text && !image) {
        return;
    }
    
    NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:2];
    
    if (text == nil || [text isEqualToString:@""]) {
        [params setObject:@"分享图片" forKey:@"status"];
    }else{
        [params setObject:text forKey:@"status"];
    }
	
    if (image) {
		[params setObject:image forKey:@"pic"];
        
        [self loadRequestWithUrl:@"https://upload.api.weibo.com/2/statuses/upload.json"
                      httpMethod:@"POST"
                          params:params
                    postDataType:kOFRequestPostDataTypeMultipart
                httpHeaderFields:nil];
    } else {
        [self loadRequestWithUrl:@"https://api.weibo.com/2/statuses/update.json"
                      httpMethod:@"POST"
                          params:params
                    postDataType:kOFRequestPostDataTypeNormal
                httpHeaderFields:nil];
    }
}

- (void)requestCountsWithWeiboIds:(NSArray *)weiboIds
{
    NSString * idsStr = [weiboIds componentsJoinedByString:@","];
    NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:1];
    [params setObject:idsStr forKey:@"ids"];
    [self loadRequestWithUrl:@"https://api.weibo.com/2/statuses/count.json"
                  httpMethod:@"GET"
                      params:params
                postDataType:kOFRequestPostDataTypeNone
            httpHeaderFields:nil];
}

- (void)requestCommentsWithWeiboId:(NSString *)weiboId
                           sinceId:(NSString *)sinceId
                             maxId:(NSString *)maxId
                            length:(NSInteger)length
{
    if (!weiboId) {
        return;
    }
    
    NSMutableDictionary * params = [NSMutableDictionary dictionaryWithCapacity:0];
    [params setObject:weiboId forKey:@"id"];
    [params setObject:[NSString stringWithFormat:@"%d", length] forKey:@"count"];
    if (sinceId) {
        [params setObject:sinceId forKey:@"since_id"];
    }
    if (maxId) {
        [params setObject:maxId forKey:@"max_id"];
    }
    
    [self loadRequestWithUrl:@"https://api.weibo.com/2/comments/show.json"
                  httpMethod:@"GET"
                      params:params
                postDataType:kOFRequestPostDataTypeNone
            httpHeaderFields:nil];
}

- (void)sendCommentWithWeiboId:(NSString *)weiboId text:(NSString *)text commentOri:(BOOL)commentOri
{
    if (!weiboId && !text) {
        return;
    }
    
    NSMutableDictionary * params = [NSMutableDictionary dictionaryWithCapacity:0];
    [params setObject:weiboId forKey:@"id"];
    [params setObject:text forKey:@"comment"];
    if (commentOri) {
        [params setObject:@"1" forKey:@"comment_ori"];
    }
    
    [self loadRequestWithUrl:@"https://api.weibo.com/2/comments/create.json"
                  httpMethod:@"POST"
                      params:params
                postDataType:kOFRequestPostDataTypeNormal
            httpHeaderFields:nil];
}

- (void)requestUserProfile
{
    [self requestOtherUserProfile:self.userId];
}

/*
 * 帐户相关/获取其他人资料
 */
- (void)requestOtherUserProfile:(NSString *)uId
{
    NSMutableDictionary * params = [NSMutableDictionary dictionaryWithCapacity:0];
    if (uId) {
        [params setObject:uId forKey:@"uid"];
    }
    [self loadRequestWithUrl:[NSString stringWithFormat:@"https://api.weibo.com/2/users/show.json"]
                  httpMethod:@"GET"
                      params:params
                postDataType:kOFRequestPostDataTypeNone
            httpHeaderFields:nil];
}

#pragma mark - OFRequestDelegate Methods
- (void)request:(OFRequest *)request didFinishLoadingWithResult:(NSString *)result
{
    [self retain];
    request.delegate = nil;
    [_requestAry removeObjectIdenticalTo:request];
    NSError * error = nil;
    NSDictionary * jsonDict = [self parseJSONString:result error:&error];
    BOOL failed = NO;
    if (!error) {
        if ([jsonDict isKindOfClass:[NSDictionary class]]) {
            id errorCodeStr = [jsonDict objectForKey:@"error_code"];
            id errorStr = [jsonDict objectForKey:@"error"];
            if (errorCodeStr && errorStr) {
                failed = YES;
                if ([errorCodeStr intValue] == 21315) {
                    // 授权超时
                    [self delegateEngineAuthorizeExpired];
                    [self release];
                    return;
                }
            }
        }
    } else {
        failed = YES;
    }
    
    if (failed) {
        [self delegateEngineRequestDidFailWithError:error];
    } else {
        [self delegateEngineRequestDidSucceedWithResult:jsonDict];
    }
    [self release];
}


@end
